/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "网格类JIT函数.h"

#include <面/面.h>



static void f_多边形_销毁边(S_边* edge) {
	delete edge;
}

static uint32 f_多边形_边数量(S_边* edge) {
	return edge->edge.size();
}

static S_多边形元素* f_多边形_桥接(S_多边形* self, S_边* 边A, S_边* 边B) {
	if (!边A || !边B) return nullptr;
	return f_surface_多边形桥接(self, *边A, *边B);
}

static S_多边形元素* f_多边形_边采样(S_边* 边, const void* c采样系数, void* c采样坐标, void* c采样线向量) {
	auto& 采样系数 = *((std::vector<float32>*)c采样系数);
	auto& 采样坐标 = *((std::vector<vec3>*)c采样坐标);
	auto& 采样线向量 = *((std::vector<vec3>*)c采样线向量);
}

uvec2* f_多边形_边_data(S_边* self) {
	return self->edge.data();
}

static S_多边形元素Array* f_多边形_复制(S_多边形* self, S_多边形元素* 元素, const S_Vec3Array* loc, const S_Vec3Array* rot, const S_Vec3Array* scal, uint32 num, uint8 合并元素) {
	if (num == -1) num = 1;
	S_多边形元素Array* 元素组 = (S_多边形元素Array*)f_core_array_new(num, sizeof(S_多边形元素*), true);

	bool 单例1 = loc->count < num;
	bool 单例2 = rot->count < num;
	bool 单例3 = scal->count < num;


	self->m_顶点.reserve(self->m_顶点.size() + 24 * num);
	self->m_法线.reserve(self->m_法线.size() + 24 * num);
	self->m_面.reserve(self->m_面.size() + num);

	for (uint32 i = 0; i < num; ++i) {
		vec3 l;
		vec3 r;
		vec3 s;

		if (单例1) l = loc->ptr_userData[0];
		else l = loc->ptr_userData[i];

		if (单例2) r = rot->ptr_userData[0];
		else r = rot->ptr_userData[i];

		if (单例3) s = scal->ptr_userData[0];
		else s = scal->ptr_userData[i];

		S_多边形元素* face = f_surface_复制(self, 元素, l, r, s, 合并元素);

		元素组->ptr_userData[i] = face;
		//switch (合并元素) {
		//	case 0: 元素组->ptr_userData[i] = face; break;
		//	case 1: 元素组->ptr_userData[i+1] = face; break;
		//}
	}

	return 元素组;
}


static S_多边形元素Array* f_多边形_复制多边形(S_多边形* self, S_多边形* 源多边形, const S_Vec3Array* loc, const S_Vec3Array* rot, const S_Vec3Array* scal, uint32 num, uint8 合并元素) {
	if (num == -1) num = 0;
	S_多边形元素Array* 元素组 = (S_多边形元素Array*)f_core_array_new(num, sizeof(S_多边形元素*), true);

	if (num) {
		bool 多例1 = loc->count >= num;
		bool 多例2 = rot->count >= num;
		bool 多例3 = scal->count >= num;


		self->m_顶点.reserve(self->m_顶点.size() + 24 * num);
		self->m_法线.reserve(self->m_法线.size() + 24 * num);
		self->m_面.reserve(self->m_面.size() + num);

		uint32 面数量 = 源多边形->m_面.size();

		S_多边形元素* 多边形元素 = (S_多边形元素*)f_core_array_new(面数量, sizeof(S_面*));
		for (uint32 i = 0; i < 面数量; ++i) {
			多边形元素->ptr_userData[i] = 源多边形->m_面[i];
		}

		self->m_UV = 源多边形->m_UV;
		self->m_UV索引 = 源多边形->m_UV索引;
		self->m_UV层数量 = 源多边形->m_UV层数量;

		for (uint32 i = 0; i < num; ++i) {
			vec3 l = 多例1 ? loc->ptr_userData[i] : loc->ptr_userData[0];
			vec3 r = 多例2 ? rot->ptr_userData[i] : rot->ptr_userData[0];
			vec3 s = 多例3 ? scal->ptr_userData[i] : scal->ptr_userData[0];

			S_多边形元素* face = f_surface_复制(self, 多边形元素, l, r, s, 合并元素);
			元素组->ptr_userData[i] = face;
		}

		f_core_array_free((S_Array*)多边形元素);
	}
	return 元素组;
}




void f_JIT_构建曲线点(S_Curve3D* 曲线, S_UI32Array* 索引, const S_Vec3Array* 端点, const S_Vec3Array* 控制点A, const S_Vec3Array* 控制点B) {
	uint32 num = DEF_Max(端点->count, 控制点A->count);
	num = DEF_Max(num, 控制点B->count);

	f_core_array_resize((S_Array*)曲线, num);

	bool 端点多例 = 端点->count >= num;
	bool 控制点A多例 = 控制点A->count >= num;
	bool 控制点B多例 = 控制点B->count >= num;

	for (uint32 i = 0; i < num; ++i) {
		曲线->ptr_userData[i] = {
			端点->ptr_userData[端点多例 ? i : 0],
			控制点A->ptr_userData[控制点A多例 ? i : 0],
			控制点B->ptr_userData[控制点B多例 ? i : 0],
			{i, 0, 0xffffffff}
		};
	}

	if (索引) {
		if (num > 1) {
			--num;
		}
		else {
			num = 0;
		}
		f_core_array_resize((S_Array*)索引, num * 2);


		for (uint32 i = 0; i < num; ++i) {
			索引->ptr_userData[i * 2] = i;
			索引->ptr_userData[i * 2 + 1] = i+1;
		}
	}
}





void f_node_所有网格类节点JIT初始化() {
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_添加多边形顶点), "uvec2", "S_多边形*, S_Vec3Array*, S_Vec3Array*", f_surface_添加多边形顶点);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_添加多边形边), "S_边*", "S_多边形* self, uvec2 offset, int32, int32", f_surface_添加多边形边);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_添加多边形纹理坐标), DEF_S(uvec2), "S_多边形*, S_Vec2Array*, const S_UI32Array*, S_uVec2Array*", f_surface_添加多边形纹理坐标);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_添加多边形元素), DEF_S(S_多边形元素*), "S_多边形*, S_Vec3Array*, S_UI32Array*, S_uVec2Array*", f_surface_添加多边形元素);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_从区间索引构建多边形面), "S_多边形元素*", "S_多边形* self, uvec2 index, uvec2, uint32, bool 反向", f_surface_从区间索引构建多边形面);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取面索引), "void", "S_多边形* self, S_多边形元素* 面元素, S_1DArray* 索引", f_surface_取面索引);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_投影纹理坐标), "void", "S_多边形* poly, int32 投影类型, S_多边形元素* 面元素, const Mat44f& mat", f_surface_投影纹理坐标);



	f_代码构建_添加JIT初始化函数指针(DEF_S(f_多边形_销毁边), "void", "S_边*", f_多边形_销毁边);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_多边形_边数量), "uint32", "S_边*", f_多边形_边数量);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_多边形_边_data), "uvec2*", "S_边*", f_多边形_边_data);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_多边形_复制), DEF_S(S_多边形元素Array*), "S_多边形* self, S_多边形元素*, const S_Vec3Array*, const S_Vec3Array*, const S_Vec3Array*, uint32, uint8", f_多边形_复制);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_多边形_复制多边形), DEF_S(S_多边形元素Array*), "S_多边形* self, S_多边形*, const S_Vec3Array*, const S_Vec3Array*, const S_Vec3Array*, uint32, uint8", f_多边形_复制多边形);

	f_代码构建_添加JIT初始化函数指针(DEF_S(f_多边形_桥接), DEF_S(S_多边形元素*), "S_多边形* self, S_边* 边A, S_边* 边B", f_多边形_桥接);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_点桥接), DEF_S(S_Vec3Array*), "const S_Vec3Array*, const S_Vec3Array*, S_UI32Array*, S_uVec2Array*", f_surface_点桥接);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_mesh_多边形三角化), "void", "S_Mesh* mesh, const S_多边形* 多边形", f_mesh_多边形三角化);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_边多点采样), "void", "S_边*, const vec2&, float32, float32, float32, float32, S_Vec3Array*, S_Vec3Array*", f_surface_边多点采样);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_边采样), "void", "S_边*, const vec2&, float32, S_Vec3Array*, S_Vec3Array*", f_surface_边采样);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_构建预设多边形), DEF_S(S_多边形元素*), "S_多边形* poly, const uvec3&, const vec3&, uint8", f_surface_构建预设多边形);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_线实体化), DEF_S(S_多边形元素Array*), "S_边Array*, S_Vec3Array*, S_F32Array*, const S_曲线&, int32, int32 ", f_surface_线实体化);
	//f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_销毁多边形元素), "void", "S_多边形元素* 面组", f_surface_销毁多边形元素);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_复制), DEF_S(S_多边形元素*), "S_多边形*, S_多边形元素*, const vec3&, const vec3&, const vec3&, uint8", f_surface_复制);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_拷贝多边形), DEF_S(S_多边形Array*), "const S_多边形Array*, S_多边形Array*, const S_Vec3Array*, const S_Vec3Array*, const S_Vec3Array*", f_surface_拷贝多边形);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_多边形变换), DEF_S(void), "S_多边形*, const vec3&, const vec3&, const vec3&", f_surface_多边形变换);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_多边形元素变换), DEF_S(void), "S_多边形元素*, const vec3&, const vec3&, const vec3&", f_surface_多边形元素变换);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_多边形元素组变换), DEF_S(void), "S_多边形元素Array*, const S_Vec3Array*, const S_Vec3Array*, const S_Vec3Array*", f_surface_多边形元素组变换);


	//f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_释放元素), DEF_S(void), "S_多边形*, S_多边形元素*", f_surface_释放元素);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_释放元素组), DEF_S(void), "S_多边形*, S_多边形元素Array*", f_surface_释放元素组);


	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取面顶点), "void", "const S_面*, S_Vec3Array*", f_surface_取面顶点);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取面法线), "void", "const S_面*, S_Vec3Array*", f_surface_取面法线);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取面中心), "void", "const S_面*, S_Vec3Array*", f_surface_取面中心);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取面顶点法线), "void", "const S_面*, S_Vec3Array*", f_surface_取面顶点法线);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取多边形边), DEF_S(S_边*), "const S_多边形* self, uint32 ID", f_surface_取多边形边);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取多边形元素), DEF_S(S_多边形元素*), "S_多边形* self, uint32 元素索引", f_surface_取多边形元素);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取多边形多个元素), DEF_S(S_多边形元素Array*), "S_多边形* self, S_UI32Array* 元素索引", f_surface_取多边形多个元素);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取多边形面), DEF_S(S_面*), "S_多边形元素* , uint32 ", f_surface_取多边形面);

	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取面元素中心), "void", "const S_多边形元素*, S_Vec3Array*", f_surface_取面元素中心);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_取多边形面中心), "void", "const S_多边形*, S_Vec3Array*", f_surface_取多边形面中心);


	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_get网格顶点数据), DEF_S(void), "S_Mesh*, const S_UI32Array*, S_Vec3Array*, int32", f_surface_get网格顶点数据);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_set网格顶点数据), DEF_S(void), "S_Mesh*, const S_UI32Array*, const S_Vec3Array*, int32", f_surface_set网格顶点数据);

	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置面顶点), "void", "const S_面*, const S_Vec3Array*", f_surface_设置面顶点);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置面顶点法线), "void", "const S_面*, const S_Vec3Array*", f_surface_设置面顶点法线);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置面法线), "void", "const S_面*, const S_Vec3Array*", f_surface_设置面法线);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置面中心), "void", "S_多边形*, const S_面*, const S_Vec3Array*", f_surface_设置面中心);

	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置面平滑模式), DEF_S(void), "S_面* 面, bool 平直", f_surface_设置面平滑模式);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置元素平滑模式), DEF_S(void), "const S_多边形元素* 元素, S_BoolArray* 平直", f_surface_设置元素平滑模式);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置元素组平滑模式), DEF_S(void), "const S_多边形元素Array* 元素组, S_BoolArray* 平直", f_surface_设置元素组平滑模式);

	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置元素UV环), "void", "S_多边形*, S_多边形元素*, S_uVec2Array*, uint32 uv层", f_surface_设置元素UV环);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置元素组UV环), "void", "S_多边形*, S_多边形元素Array*, S_uVec2Array*, uint32 uv层", f_surface_设置元素组UV环);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置元素材质槽ID), "void", "S_多边形*, const S_多边形元素*, S_UI32Array*", f_surface_设置元素材质槽ID);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置元素组材质槽ID), "void", "S_多边形*, const S_多边形元素Array*, S_UI32Array*", f_surface_设置元素组材质槽ID);


	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_创建自定义属性), DEF_S(void), "S_多边形* , S_网格自定义属性* ", f_surface_创建自定义属性);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置自定义属性), DEF_S(void), "S_多边形* 多边形, S_网格自定义属性* 类型, S_Array* a", f_surface_设置自定义属性);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置面自定义属性), DEF_S(void), "S_多边形元素* , S_网格自定义属性* , S_Array* a", f_surface_设置面自定义属性);
	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_设置元素自定义属性), DEF_S(void), "S_多边形元素Array* , S_网格自定义属性* , S_Array* a", f_surface_设置元素自定义属性);


	f_代码构建_添加JIT初始化函数指针(DEF_S(f_surface_点), DEF_S(S_Vec3Array*), "const S_Vec3Array* 点, const S_Vec3Array* loc", f_surface_点);



	f_代码构建_添加JIT初始化函数指针(DEF_S(f_JIT_构建曲线点), DEF_S(void), "S_Curve3D* , S_UI32Array* , const S_Vec3Array* , const S_Vec3Array* , const S_Vec3Array* ", f_JIT_构建曲线点);

}





